package com.feonix.common.util.mvc;

import com.feonix.common.BaseInfo;
import com.feonix.common.util.JsonUtil;
import com.feonix.common.util.StringUtil;
import com.feonix.common.view.tree.Tree;
import com.feonix.common.view.tree.TreeNode;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Script {
	private Log logger = LogFactory.getLog(getClass());

	private List<String> scripts = new ArrayList<String>();
	private boolean needScriptTag = false;
	private boolean jsLib = false;
	private boolean enableSubmit = true;
	private String path = "";

	private Script() {
	}

	private Script(boolean jsLib) {
		this.jsLib = jsLib;
		this.path = "parent";
	}

	/**
	 * 构造一个Script
	 * 
	 * @return
	 */
	public static Script getInstance() {
		return new Script();
	}

	/**
	 * 构造一个Script，并且带js库，通常用在提交到iframe的输出，path默认为parent
	 * 
	 * @return
	 */
	public static Script getInstanceWithJsLib() {
		Script script = new Script(true);
		script.setNeedScriptTag(true);
		return script;
	}

	/**
	 * 构造一个Script，不带js库，通常用在提交到iframe的输出
	 * 
	 * @return
	 */
	public static Script getInstanceOnly() {
		Script script = new Script(false);
		script.setNeedScriptTag(true);
		script.setEnableSubmit(false);
		return script;
	}

	/**
	 * 增加alert的提示
	 * 
	 * @param message
	 * @return
	 */
	public Script addAlert(String message) {
		this.scripts.add("alert('" + StringUtil.escapeJS(StringUtil.getString(message)) + "');\n");
		return this;
	}

	/**
	 * 增加alert的提示
	 * 
	 * @param message
	 * @param function
	 * @return
	 */
	public Script addAlert(String message, String function) {
		this.scripts.add(
				"alert('" + StringUtil.escapeJS(StringUtil.getString(message)) + "', 'warning', " + function + ");\n");
		return this;
	}

	/**
	 * 增加script
	 * 
	 * @param script
	 * @return
	 */
	public Script addScript(String script) {
		if (StringUtil.isEmpty(script)) {
			return this;
		}
		if (!script.endsWith(";")) {
			script = script + ";";
		}
		this.scripts.add(script + "\n");
		return this;
	}

	/**
	 * 增加script
	 * 
	 * @param function
	 * @param params
	 * @return
	 */
	public Script addScript(String function, Object... params) {
		if (StringUtil.isEmpty(function)) {
			return this;
		}
		String script = null;
		if (ArrayUtils.isNotEmpty(params)) {
			StringBuffer sb = new StringBuffer();
			ArrayList<String> tmpList = new ArrayList<String>();
			String str2 = null;
			sb.append(function).append("(");
			Object[] objects;
			int j = (objects = params).length;
			for (int i = 0; i < j; i++) {
				Object object = objects[i];
				str2 = StringUtil.escapeJS(StringUtil.getString(object));
				if (str2.startsWith("js:")) {
					tmpList.add(StringUtil.replaceFirst(str2, "js:", ""));
				} else {
					tmpList.add("'" + str2 + "'");
				}
			}
			sb.append(StringUtil.join(tmpList, ","));
			sb.append(");");
			script = sb.toString();
			StringUtil.cleanStringBuffer(new StringBuffer[] { sb });
		} else {
			script = function + "();";
		}
		this.scripts.add(script + "\n");
		return this;
	}

	/**
	 * 创建一个script，组织一个js调用，例如xxxx('a','b'....)
	 * 
	 * @param function
	 * @param params
	 * @return
	 */
	public static String createScript(String function, Object... params) {
		String script = "";
		if (StringUtil.isEmpty(function)) {
			return script;
		}
		if (ArrayUtils.isNotEmpty(params)) {
			StringBuffer sb = new StringBuffer();
			ArrayList<String> tmpList = new ArrayList<String>();
			String str2 = null;
			sb.append(function).append("(");
			Object[] objects;
			int j = (objects = params).length;
			for (int i = 0; i < j; i++) {
				Object object = objects[i];
				str2 = StringUtil.escapeJS(StringUtil.getString(object));
				if (str2.startsWith("js:")) {
					tmpList.add(StringUtil.replaceFirst(str2, "js:", ""));
				} else {
					tmpList.add("'" + str2 + "'");
				}
			}
			sb.append(StringUtil.join(tmpList, ","));
			sb.append(");");
			script = sb.toString();
			StringUtil.cleanStringBuffer(new StringBuffer[] { sb });
		} else {
			script = function + "();";
		}
		return script;
	}

	/**
	 * 去除遮罩
	 * 
	 * @return
	 */
	public Script removeLoadMask() {
		String str = "$('body').unmask();";
		if (StringUtil.isNotEmpty(this.path)) {
			str = this.path + "." + str;
		}
		this.scripts.add(str);
		return this;
	}

	/**
	 * 刷新当前页面
	 * 
	 * @return
	 */
	public Script reload() {
		this.scripts.add("window.location.reload();\n");
		return this;
	}

	/**
	 * 刷新父页面
	 * 
	 * @return
	 */
	public Script reloadParent() {
		this.scripts.add("parent.location.reload();\n");
		return this;
	}

	/**
	 * 关闭窗口
	 * 
	 * @return
	 */
	public Script closeDialog() {
		this.scripts.add("closeDialog();\n");
		return this;
	}

	@Deprecated
	public Script closeDialogWithSelf() {
		this.scripts.add("closeDialog();\n");
		return this;
	}

	public Script closeDialogAndReload() {
		this.scripts.add("closeDialog(true);\n");
		return this;
	}

	@Deprecated
	public Script closeDialogAndReloadWithSelf() {
		this.scripts.add("closeDialog(true);\n");
		return this;
	}

	/**
	 * 获得组织的script语句
	 * 
	 * @return
	 */
	public String getScript() {
		StringBuffer sb = new StringBuffer();
		if (this.jsLib) {
			sb.append("<script type=\"text/javascript\" src=\"");
			sb.append(BaseInfo.getContextPath());
			sb.append("/ui/lib/jquery/jquery.min.js\"></script>\n");
			sb.append("<script type=\"text/javascript\" src=\"");
			sb.append(BaseInfo.getContextPath());
			sb.append("/ui/script/ui.js\"></script>\n");
		}
		if (this.needScriptTag) {
			sb.append("<script type=\"text/javascript\">\n");
		}
		if (this.enableSubmit) {
			enableSubmit(sb);
		}
		for (Iterator<String> iterator = this.scripts.iterator(); iterator.hasNext();) {
			String script = iterator.next();
			sb.append(script);
		}
		if (this.needScriptTag) {
			sb.append("</script>\n");
		}
		String str = sb.toString();
		logger.debug(str);
		StringUtil.cleanStringBuffer(new StringBuffer[] { sb });
		return str;
	}

	private void enableSubmit(StringBuffer paramStringBuffer) {
		if (StringUtil.isNotEmpty(this.path)) {
			paramStringBuffer.append(this.path + ".");
		}
		paramStringBuffer.append("$('form').each(");
		paramStringBuffer.append("function(index, element){var form = $(element);");
		paramStringBuffer.append("var submitBtn = $(form.find('[type=submit]'));");
		paramStringBuffer.append("submitBtn.attr('disabled',false).removeClass('disabled');");
		paramStringBuffer.append("});\n");
	}

	private String treeTarget = "top.menu";
	private String treeDomId = "tree";

	public Script addNodes(List<TreeNode> paramList) {
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(this.treeTarget).append(".");
		stringBuffer.append("$('#");
		stringBuffer.append(this.treeDomId);
		stringBuffer.append("').tree().addNodes(" + Tree.parse(paramList) + ");");
		String str = stringBuffer.toString();
		StringUtil.cleanStringBuffer(new StringBuffer[] { stringBuffer });
		addScript(str);
		return this;
	}

	public Script removeNodes(String... paramVarArgs) {
		String str1 = this.treeTarget + ".$('#" + this.treeDomId + "').tree()";
		StringBuffer stringBuffer = new StringBuffer();
		String[] arrayOfString;
		int j = (arrayOfString = paramVarArgs).length;
		for (int i = 0; i < j; i++) {
			String str2 = arrayOfString[i];
			stringBuffer.append(str1);
			stringBuffer.append(".removeNode('");
			stringBuffer.append(str2);
			stringBuffer.append("');");
		}
		str1 = stringBuffer.toString();
		StringUtil.cleanStringBuffer(new StringBuffer[] { stringBuffer });
		addScript(str1);
		return this;
	}

	public Script refreshNode(String... paramVarArgs) {
		String str1 = this.treeTarget + ".$('#" + this.treeDomId + "').tree()";
		StringBuffer stringBuffer = new StringBuffer();
		String[] arrayOfString;
		int j = (arrayOfString = paramVarArgs).length;
		for (int i = 0; i < j; i++) {
			String str2 = arrayOfString[i];
			stringBuffer.append(str1);
			stringBuffer.append(".refreshNode('");
			stringBuffer.append(str2);
			stringBuffer.append("');");
		}
		str1 = stringBuffer.toString();
		StringUtil.cleanStringBuffer(new StringBuffer[] { stringBuffer });
		addScript(str1);
		return this;
	}

	public Script updateNode(TreeNode paramTreeNode) {
		String str = this.treeTarget + ".$('#" + this.treeDomId + "').tree().updateNode("
				+ JsonUtil.objectToString(paramTreeNode) + ");";
		addScript(str);
		return this;
	}

	public Script setTreeTarget(String treeTarget) {
		this.treeTarget = treeTarget;
		return this;
	}

	public Script setTreeDomId(String treeDomId) {
		this.treeDomId = treeDomId;
		return this;
	}

	public String getPath() {
		return this.path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public boolean isEnableSubmit() {
		return this.enableSubmit;
	}

	public void setEnableSubmit(boolean enableSubmit) {
		this.enableSubmit = enableSubmit;
	}

	public boolean isNeedScriptTag() {
		return this.needScriptTag;
	}

	public void setNeedScriptTag(boolean needScriptTag) {
		this.needScriptTag = needScriptTag;
	}
}
